package com.xinggq.common.exception;

import com.xinggq.common.enums.ResponseEnum;
import lombok.Getter;
import lombok.Setter;

import java.io.Serial;

/**
 * 通用业务异常抽象类
 * 提供统一的异常处理机制，支持错误码、错误信息和附加数据
 * 所有业务异常都应该继承此类
 * 注意：此类为抽象类，不能直接实例化，请使用静态工厂方法创建实例
 *
 * @author xinggq
 * @since 2025/10/21
 */
@Getter
@Setter
public abstract class AbstractCommonException extends RuntimeException {

  @Serial
  private static final long serialVersionUID = 1L;

  /**
   * 错误码
   */
  protected Integer code;

  /**
   * 错误信息
   */
  protected String message;

  /**
   * 附加数据，用于传递额外的错误信息
   */
  protected Object data;

  /**
   * 核心构造函数 - 基于响应枚举
   * 
   * @param responseEnum 响应枚举，包含错误码和默认消息
   */
  protected AbstractCommonException(ResponseEnum responseEnum) {
    super(responseEnum.getMsg());
    this.code = responseEnum.getCode();
    this.message = responseEnum.getMsg();
  }

  /**
   * 核心构造函数 - 基于响应枚举和自定义消息
   * 
   * @param responseEnum 响应枚举，提供错误码
   * @param message 自定义错误信息
   */
  protected AbstractCommonException(ResponseEnum responseEnum, String message) {
    super(message);
    this.code = responseEnum.getCode();
    this.message = message;
  }

  /**
   * 核心构造函数 - 基于响应枚举和原始异常
   * 
   * @param responseEnum 响应枚举，包含错误码和默认消息
   * @param cause 原始异常
   */
  protected AbstractCommonException(ResponseEnum responseEnum, Throwable cause) {
    super(responseEnum.getMsg(), cause);
    this.code = responseEnum.getCode();
    this.message = responseEnum.getMsg();
  }

  /**
   * 核心构造函数 - 完整参数版本
   * 
   * @param responseEnum 响应枚举，提供错误码
   * @param message 自定义错误信息
   * @param cause 原始异常
   */
  protected AbstractCommonException(ResponseEnum responseEnum, String message, Throwable cause) {
    super(message, cause);
    this.code = responseEnum.getCode();
    this.message = message;
  }

  /**
   * 设置附加数据
   *
   * @param data 附加数据
   * @return 当前异常实例，支持链式调用
   */
  protected AbstractCommonException setData(Object data) {
    this.data = data;
    return this;
  }

  // ==================== 通用静态工厂方法 ====================


  /**
   * 创建参数错误异常
   *
   * @param paramName 参数名称
   * @return CommonException实例
   */
  public static AbstractCommonException paramError(String paramName) {
    return new AbstractCommonException(ResponseEnum.PARAMS_ERROR, "参数错误: " + paramName) {};
  }


  /**
   * 创建参数为空异常
   *
   * @param paramName 参数名称
   * @return CommonException实例
   */
  public static AbstractCommonException paramNull(String paramName) {
    return new AbstractCommonException(ResponseEnum.PARAM_IS_NULL, "参数不能为空: " + paramName) {};
  }

  /**
   * 创建数据为空异常
   *
   * @param message 自定义错误信息
   * @return CommonException实例
   */
  public static AbstractCommonException dataNull(String message) {
    return new AbstractCommonException(ResponseEnum.DATA_IS_NULL, message) {};
  }

  /**
   * 创建数据已存在异常
   *
   * @param dataName 数据名称
   * @return CommonException实例
   */
  public static AbstractCommonException dataExists(String dataName) {
    return new AbstractCommonException(ResponseEnum.NAME_IS_EXISTS, "数据已存在: " + dataName) {};
  }

  /**
   * 创建数据不存在异常
   *
   * @param dataName 数据名称
   * @return CommonException实例
   */
  public static AbstractCommonException dataNotFound(String dataName) {
    return new AbstractCommonException(ResponseEnum.QUERY_EMPTY, "数据不存在: " + dataName) {};
  }

  /**
   * 创建业务错误异常
   *
   * @param message 错误信息
   * @return CommonException实例
   */
  public static AbstractCommonException businessError(String message) {
    return new AbstractCommonException(ResponseEnum.REQUEST_FAIL, message) {};
  }

  /**
   * 创建系统错误异常
   *
   * @return CommonException实例
   */
  public static AbstractCommonException systemError() {
    return new AbstractCommonException(ResponseEnum.UNKNOWN_ERROR) {};
  }

  /**
   * 创建系统错误异常
   *
   * @param message 自定义错误信息
   * @return CommonException实例
   */
  public static AbstractCommonException systemError(String message) {
    return new AbstractCommonException(ResponseEnum.UNKNOWN_ERROR, message) {};
  }

  /**
   * 创建系统错误异常（包装其他异常）
   *
   * @param cause 原始异常
   * @return CommonException实例
   */
  public static AbstractCommonException systemError(Throwable cause) {
    return new AbstractCommonException(ResponseEnum.UNKNOWN_ERROR, cause) {};
  }

  /**
   * 创建认证失败异常
   *
   * @return CommonException实例
   */
  public static AbstractCommonException authFailure() {
    return new AbstractCommonException(ResponseEnum.AUTH_FAILURE) {};
  }

  /**
   * 创建认证失败异常
   *
   * @param message 自定义错误信息
   * @return CommonException实例
   */
  public static AbstractCommonException authFailure(String message) {
    return new AbstractCommonException(ResponseEnum.AUTH_FAILURE, message) {};
  }

  /**
   * 创建权限不足异常
   *
   * @return CommonException实例
   */
  public static AbstractCommonException noPermission() {
    return new AbstractCommonException(ResponseEnum.AUTH_NO_PERMISSION) {};
  }

  /**
   * 创建权限不足异常
   *
   * @param operation 操作名称
   * @return CommonException实例
   */
  public static AbstractCommonException noPermission(String operation) {
    return new AbstractCommonException(ResponseEnum.AUTH_NO_PERMISSION, "权限不足，无法执行操作: " + operation) {};
  }

  /**
   * 创建请求过于频繁异常
   *
   * @return CommonException实例
   */
  public static AbstractCommonException tooManyRequests() {
    return new AbstractCommonException(ResponseEnum.REQUEST_FAIL, "请求过于频繁") {};
  }

  /**
   * 创建服务不可用异常
   *
   * @return CommonException实例
   */
  public static AbstractCommonException serviceUnavailable() {
    return new AbstractCommonException(ResponseEnum.UNKNOWN_ERROR, "服务不可用") {};
  }

  /**
   * 创建服务不可用异常
   *
   * @param serviceName 服务名称
   * @return CommonException实例
   */
  public static AbstractCommonException serviceUnavailable(String serviceName) {
    return new AbstractCommonException(ResponseEnum.UNKNOWN_ERROR, "服务不可用: " + serviceName) {};
  }

  /**
   * 创建文件上传失败异常
   *
   * @return CommonException实例
   */
  public static AbstractCommonException fileUploadFailed() {
    return new AbstractCommonException(ResponseEnum.FILE_UPLOAD_ERROR) {};
  }

  /**
   * 创建文件上传失败异常
   *
   * @param fileName 文件名
   * @return CommonException实例
   */
  public static AbstractCommonException fileUploadFailed(String fileName) {
    return new AbstractCommonException(ResponseEnum.FILE_UPLOAD_ERROR, "文件上传失败: " + fileName) {};
  }

  /**
   * 创建文件下载失败异常
   *
   * @return CommonException实例
   */
  public static AbstractCommonException fileDownloadFailed() {
    return new AbstractCommonException(ResponseEnum.FILE_TYPE_ERROR, "文件下载失败") {};
  }

  /**
   * 创建文件下载失败异常
   *
   * @param fileName 文件名
   * @return CommonException实例
   */
  public static AbstractCommonException fileDownloadFailed(String fileName) {
    return new AbstractCommonException(ResponseEnum.FILE_TYPE_ERROR, "文件下载失败: " + fileName) {};
  }

  /**
   * 重写getMessage方法，确保返回自定义的message
   */
  @Override
  public String getMessage() {
    return this.message;
  }

  /**
   * 获取详细的异常信息，包含错误码和错误信息
   *
   * @return 详细异常信息
   */
  public String getDetailMessage() {
    return String.format("[%d] %s", this.code, this.message);
  }

  /**
   * 判断是否为指定的错误码
   *
   * @param responseEnum 响应枚举
   * @return 是否匹配
   */
  public boolean isCode(ResponseEnum responseEnum) {
    return responseEnum != null && responseEnum.getCode() == this.code;
  }

  /**
   * 判断是否为指定的错误码
   *
   * @param code 错误码
   * @return 是否匹配
   */
  public boolean isCode(Integer code) {
    return code != null && code.equals(this.code);
  }
}